/*****************************/
/** ENTREPRENEUR - EXCLUDED **/
/*****************************/


double focEC(const double xval, void * params){
    
    struct paramsgolden *focparams= (struct paramsgolden *) params;
    
    // Values and relevant policy functions in R and B //
    double *valueEhatnextfoc=focparams->valueEhatnextST;
#if OPT_compute_C_flow == 1
    double *C_Ehatnextfoc=focparams->C_EhatnextST;
#endif
    double *saveEhatnext=focparams->saveEhatnextST;
    double *searchEhatnext=focparams->searchEhatnextST;
    
#if SEA == 1
    double *valueEhatinextfoc=focparams->valueEhatinextST;
#if OPT_compute_C_flow == 1
    double *C_Ehatinextfoc=focparams->C_EhatinextST;
#endif
    double *saveEhatinext=focparams->saveEhatinextST;
    double *searchEhatinext=focparams->searchEhatinextST;
#endif
    
    int tgridfoc=focparams->tgridST; int igridfoc=focparams->igridST; int zgridfoc=focparams->zgridST; 
    int Jinsured=focparams->JinsuredST;
    
    double xgrid, dxgrid, tempJE, COH, value, C_value, save, search, valfoc, profitEhat, muENDO,C_tempJE;
    int ixgrid, ixgridMU;
    double optival[maxfirmtype], optisave[maxfirmtype], optisearch[maxfirmtype];
    
    
    // CONTINUATION VALUE //
    tempJE   = 0.0;
    C_tempJE = 0.0;
    for(int zz=0; zz<maxfirmtype;zz++) {
        
        COH     = findCOH_Ehat(igridfoc, zz, tgridfoc, xval, Jinsured);
        xgrid   = invexpspace(COH,GridminCOH,GridmaxCOH,EchelleCOH,maxgridCOH);
        dxgrid  = weightinter(COH, xgrid, &ixgrid, gridCOH, maxgridCOH);
        if ((ixgrid>=(maxgridCOH-1))){printf("focEhat: ixgrid>=(maxgrid-1) %d\n",ixgrid);getchar();}
        if ((COH<(0.0))){printf("focEhat: (COH<(0.0)) %20.15f\n",COH);getchar();}
        
        // COMPUTE THE INDUCED POLICIES //
        if(Jinsured == 0){
            value   = inter1d(dxgrid,valueEhatnextfoc[inxRB((ixgrid),tgridfoc,zz)],valueEhatnextfoc[inxRB((ixgrid+1),tgridfoc,zz)]);
#if OPT_compute_C_flow == 1
            C_value = inter1d(dxgrid,C_Ehatnextfoc[inxRB((ixgrid),tgridfoc,zz)],C_Ehatnextfoc[inxRB((ixgrid+1),tgridfoc,zz)]);
#endif
            save    = inter1d(dxgrid,saveEhatnext[inxRB((ixgrid),tgridfoc,zz)],saveEhatnext[inxRB((ixgrid+1),tgridfoc,zz)]);
            search  = inter1d(dxgrid,searchEhatnext[inxRB((ixgrid),tgridfoc,zz)],searchEhatnext[inxRB((ixgrid+1),tgridfoc,zz)]);
        }
        
        
#if SEA == 1
        if(Jinsured == 1){
            profitEhat  = profitEhatfun(igridfoc, zz, tgridfoc, xval);
            muENDO      = muendoSEA(profitEhat,tgridfoc);
            //muENDO      = min(max(0.0,mupar*(bstarcostfun(profitEhat,tgridfoc)/((1.0-taxrate)*rhostar*wstar*prod[tgridfoc]))),mupar);
            if(muENDO > mupar+0.000000001 || muENDO < 0.0){printf("mu: %f, profitEhat = %f", muENDO, profitEhat);getchar();}
            
            value = muENDO*inter1d(dxgrid,valueEhatnextfoc[inxRB((ixgrid),tgridfoc,zz)],valueEhatnextfoc[inxRB((ixgrid+1),tgridfoc,zz)])+
            (1.0-muENDO)*(inter1d(dxgrid,valueEhatinextfoc[inxRB((ixgrid),tgridfoc,zz)],valueEhatinextfoc[inxRB((ixgrid+1),tgridfoc,zz)]));
#if OPT_compute_C_flow == 1
            C_value = muENDO*inter1d(dxgrid,C_Ehatnextfoc[inxRB((ixgrid),tgridfoc,zz)],C_Ehatnextfoc[inxRB((ixgrid+1),tgridfoc,zz)])+
            (1.0-muENDO)*(inter1d(dxgrid,C_Ehatinextfoc[inxRB((ixgrid),tgridfoc,zz)],C_Ehatinextfoc[inxRB((ixgrid+1),tgridfoc,zz)]));
#endif
            save  = muENDO*inter1d(dxgrid,saveEhatnext[inxRB((ixgrid),tgridfoc,zz)],saveEhatnext[inxRB((ixgrid+1),tgridfoc,zz)])+
            (1.0-muENDO)*(inter1d(dxgrid,saveEhatinext[inxRB((ixgrid),tgridfoc,zz)],saveEhatinext[inxRB((ixgrid+1),tgridfoc,zz)]));
            search = muENDO*inter1d(dxgrid,searchEhatnext[inxRB((ixgrid),tgridfoc,zz)],searchEhatnext[inxRB((ixgrid+1),tgridfoc,zz)])+
            (1.0-muENDO)*(inter1d(dxgrid,searchEhatinext[inxRB((ixgrid),tgridfoc,zz)],searchEhatinext[inxRB((ixgrid+1),tgridfoc,zz)]));
        }
#endif
        
        // save the values associated to this state //
        optival[zz]     = value;
        optisave[zz]    = save;
        optisearch[zz]  = search;
        tempJE          += mzprob[zgridfoc][zz]*value;
#if OPT_compute_C_flow == 1
        C_tempJE        += mzprob[zgridfoc][zz]*C_value;
#endif
    }
    
    focparams->JE_save      =   optisave;
    focparams->JE_val       =   optival;
    focparams->JE_search    =   optisearch;
    focparams->C_val        =   C_tempJE;
    
    valfoc  =   -tempJE; // here, already positive value.
    return valfoc;
}
